package com.eolcum.evo.thread;

import java.text.DecimalFormat;

import com.eolcum.evo.calculator.PID;
import com.eolcum.evo.persistence.Room;

public class RoomTemperatureController implements Runnable {

	String tag = "RoomTemperatureControllerThread";
	Room room;
	int cycleFrequency = 1000;

	private double activeInput;
	private double activeOutput;

	public RoomTemperatureController() {
	}

	@Override
	public void run() {

		if (room.getActuators() == null || room.getActuators().size() <= 0)
			return;
		if (room.getSensors() == null || room.getSensors().size() <= 0)
			return;
		PID pid = new PID(8, 0.1, 0);
		pid.setContinuous(false);
		pid.setInputRange(10, 35);
		pid.setOutputRange(0, 100);
		pid.setTolerance(5);
		pid.enable();

		pid.setInput(12);
		while (true) {
			// Log.i(tag, "RoomTemperatureControllerRunning");
			pid.setSetpoint(room.getActualTemperatureSetpoint());
			double averageTemperature = 0;

			if (room.getSensors().size() > 1) {
				for (int i = 0; i < room.getSensors().size(); i++) {
					averageTemperature += room.getSensors().get(i)
							.getActiveTemp();
				}
				pid.setInput(averageTemperature / room.getSensors().size());
				setActiveInput(averageTemperature / room.getSensors().size());
			} else {
				pid.setInput(room.getSensors().get(0).getActiveTemp());
				setActiveInput(room.getSensors().get(0).getActiveTemp());
			}
			double output = pid.performPID();
			DecimalFormat df = new DecimalFormat("#.##");
			output = Double.valueOf(df.format(output));
			for (int i = 0; i < room.getActuators().size(); i++) {
				room.getActuators().get(i).setActiveOutput(output);
			}

			setActiveOutput(output);

			pid.setInput(pid.getInput() + 0.25);

			try {
				Thread.currentThread();
				Thread.sleep(cycleFrequency);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * @return the room
	 */
	public synchronized Room getRoom() {
		return room;
	}

	/**
	 * @param room
	 *            the room to set
	 */
	public synchronized void setRoom(Room room) {
		this.room = room;
	}

	/**
	 * @return the cycleFrequency
	 */
	public synchronized int getCycleFrequency() {
		return cycleFrequency;
	}

	/**
	 * @param cycleFrequency
	 *            the cycleFrequency to set
	 */
	public synchronized void setCycleFrequency(int cycleFrequency) {
		this.cycleFrequency = cycleFrequency;
	}

	/**
	 * @return the activeInput
	 */
	public synchronized double getActiveInput() {
		return activeInput;
	}

	/**
	 * @param activeInput
	 *            the activeInput to set
	 */
	public synchronized void setActiveInput(double activeInput) {
		this.activeInput = activeInput;
	}

	/**
	 * @return the activeOutput
	 */
	public synchronized double getActiveOutput() {
		return activeOutput;
	}

	/**
	 * @param activeOutput
	 *            the activeOutput to set
	 */
	public synchronized void setActiveOutput(double activeOutput) {
		this.activeOutput = activeOutput;
	}
}